/**
 * @file task.h
 * @author lcz (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-10-22
 *
 * @copyright Copyright (c) 2022
 *
 */

#ifndef TASK_H
#define TASK_H


#include "comm/types.h"
#include "cpu/cpu.h"
#include "tools/list.h"
#include "fs/file.h"

// macro
#define TASK_NAME_SIZE 32 // 任务名字长度
#define TASK_OFILE_NR 128 // 最多支持打开的文件数量
#define TASK_TIME_SLICE_DEFAULT 10 // 时间片计数

#define TASK_FLAGS_SYSTEM (1 << 0)


// typedef struct _tss_t2
// {
//     uint32_t pre_link;
//     uint32_t esp0, ss0, esp1, ss1, esp2, ss2;
//     uint32_t cr3;
//     uint32_t eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
//     uint32_t es, cs, ss, ds, fs, gs;
//     uint32_t ldt;
//     uint32_t io_map;
//     uint32_t ssp;
// } tss_t2;

typedef struct _task_args_t
{
    uint32_t ret_addr; // 返回地址，无用
    uint32_t argc;
    char **argv;
} task_args_t;

/**
 * @brief 定义任务结构体
 *
 */
typedef struct _task_t
{
    list_node_t run_node; // 运行相关结点
    list_node_t all_node; // 等待队列
    list_node_t wait_node; // 所有队列结点
    enum
    {
        TASK_CREATED,
        TASK_RUNNING,
        TASK_SLEEP,
        TASK_READY,
        TASK_WAITTING,
        TASK_ZOMBIE,
    } state;
    int time_ticks;  // 该进程的时间值 属性 常量
    int slice_ticks; // 当前进程的时间值
    int sleep_ticks; //
    char name[TASK_NAME_SIZE];
    int pid; // 进程的pid
    int status;
    file_t *file_table[TASK_OFILE_NR]; // 存放指针的数组
    struct _task_t * parent;
    uint32_t heap_start; //
    uint32_t heap_end; //
    tss_t tss;
    int tss_sel;
    uint32_t *stack;
    
} task_t;
/**
 * @brief 任务管器结构
 *
 */
typedef struct _task_mananger_t
{
    task_t *curr_task;
    list_t ready_list;
    list_t task_list;
    list_t sleep_list;
    task_t first_task;
    task_t idle_task;
    int app_code_sel;
    int app_data_sel;

} task_mananger_t;

int task_init(task_t *task, uint32_t entry, uint32_t esp, char *name,int flags);

void task_switch_from_to(task_t *from, task_t *to);
void switch_to_tss(int tss_sel);
// this function declare i'm not grasp
// void simple_switch(uint32_t from_stack, uint32_t to_stack);

// define task_mananger_t function
void task_manager_init(void);
void task_first_init(void);
task_t *task_first_task(void);
int sys_sched_yield(void);
task_t *task_current(void);

void task_time_tick(void);

void task_set_ready(task_t *task);
void task_set_block(task_t *task);

// about task sleep
void sys_sleep(uint32_t ms);
void task_set_sleep(task_t *task, uint32_t ticks);
void task_set_wakeup(task_t *task);
void task_dispatch(void);

int sys_getpid(void);
int sys_fork(void);
int sys_execve(char *name, char **argv, char **env);
void sys_exit(int status);
int sys_wait(int *status);

    // about file
    file_t *task_file(int fd);
int task_alloc_fd(file_t *file);
void task_remove_fd(int fd);
#endif
